﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using MVVM.Core;
using Microsoft.Office.Interop.Excel;

namespace ObjectModel.Excel
{
	public enum Dimension {Width, Height}

	/// <summary>
	/// Encapsulates logic for setting a dynamic width or height for a source range
	/// </summary>
	public class DynamicLookupDimension : NotificationBase {

		public DynamicLookupDimension(int value = 1, bool advancedmode = false, Dimension direction = Dimension.Width) 
		{ 
			AdvancedMode = advancedmode;
			Dimension = direction;
			_value = value;
		}

		public DynamicLookupDimension() { }

		#region Fields
	
		int _value = 1;
		string mHook = string.Empty;
		bool mAdvancedMode;
		string mAnchor = string.Empty;

		#endregion

		#region Properties

		/// <summary>
		/// The starting point for the dimension, usually in the same column or row as the top left cell of the found range
		/// </summary>
		public string Anchor {
			get { return mAnchor; }
			set { mAnchor = value;
				OnPropertyChanged("Anchor"); }
		}

		

		/// <summary>
		/// The cell to be found, usually in the same row or col as the StartAnchor
		/// </summary>
		public string Hook {
			get { return mHook; }
			set { mHook = value;
				OnPropertyChanged("Hook"); }
		}

		/// <summary>
		/// Whether the dimension is dynamic or not
		/// </summary>
		public bool AdvancedMode {
			get { return mAdvancedMode; }
			set { mAdvancedMode = value; 
			OnPropertyChanged("AdvancedMode");}
		}

		/// <summary>
		/// Returns the length of the dimension. If in simple mode, then this will be a hardcoded value, otherwise it will
		/// be the last fetched dynamic value
		/// </summary>
		public int Value { 
			get {
				return _value;
			}
			set
				{
					_value = value;
					AdvancedMode = false;
					OnPropertyChanged("Value");
				}
			}

		/// <summary>
		/// Whether to search horizontally or vertically
		/// </summary>
		public Dimension Dimension { get; set; }

		#endregion

		#region Methods

		/// <summary>
		/// Attempts to resolve the dynamic dimension if in advanced mode otherwise returns the Value 
		/// </summary>
		/// <returns></returns>
		public int Resolve(Range startingCell) 
		{
			int result = Value;

			// If no properties set return default
			if(!AdvancedMode || string.IsNullOrEmpty(Anchor) || string.IsNullOrEmpty(Hook))
				return result;

			if(Dimension == Dimension.Width) {
				LookUpStep firstStep = new LookUpStep() {ColAbs = startingCell.Column, LookUpSetting = LookUpBy.Col, LookUpString = Anchor, SearchDirection = SearchDirection.Previous};
				Range anchorCell = firstStep.Resolve(startingCell);
				LookUpStep secondStep = new LookUpStep(){RowAbs = anchorCell.Row, LookUpSetting = LookUpBy.Row, LookUpString = Hook};
				result = secondStep.Resolve(anchorCell).Column - startingCell.Column + 1;
			}
			else {
			
			LookUpStep firstStep = new LookUpStep() {RowAbs = startingCell.Row, LookUpSetting = LookUpBy.Row, LookUpString = Anchor, SearchDirection = SearchDirection.Previous};
			Range anchorCell = firstStep.Resolve(startingCell);
			LookUpStep secondStep = new LookUpStep(){ColAbs = anchorCell.Column, LookUpSetting = LookUpBy.Col, LookUpString = Hook};
			result = secondStep.Resolve(anchorCell).Row - startingCell.Row + 1;
			}

			_value = result;
			return result;
		}

		#endregion
	}
}
